﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using System.Threading;
using System;
using HiCore.WebApi.Example.DbContexts.DbEntity;

namespace HiCore.WebApi.Example.DbContexts.Interceptors
{
    internal class AuditInterceptor : SaveChangesInterceptor
    {
        private readonly IServiceProvider _serviceProvider;
        public AuditInterceptor(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
        {
            setConfig(eventData);
            return base.SavingChangesAsync(eventData, result, cancellationToken);
        }
        public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
        {
            setConfig(eventData);
            return base.SavingChanges(eventData, result);
        }

        private void setConfig(DbContextEventData eventData)
        {
            //var currentUser = _serviceProvider.GetRequiredService<ICurrentUserService>();

            //long userId = !string.IsNullOrEmpty(currentUser.UserId) ? long.Parse(currentUser.UserId) : 0;
            //long tenantId = !string.IsNullOrEmpty(currentUser.TenantId) ? long.Parse(currentUser.TenantId) : 0;

            long userId = 0;
            long tenantId = 0;

            DateTime dtNow = DateTime.Now;
            DateTime dtMin = System.Data.SqlTypes.SqlDateTime.MinValue.Value.ToLocalTime();
            SetAttr<AuditableEntityAggregateRoot>(eventData, tenantId, userId, dtNow, dtMin);
            SetAttr<AuditableEntity>(eventData, tenantId, userId, dtNow, dtMin);
        }

        private void SetAttr<TAttribute>(DbContextEventData eventData, long tenantId, long userId, DateTime dtNow,DateTime dtMin) where TAttribute : class, IAuditableEntity
        {
            foreach (var entry in eventData.Context.ChangeTracker.Entries<TAttribute>())
            {
                switch (entry.State)
                {
                    case EntityState.Added:
                        entry.Entity.TenantId = tenantId;
                        entry.Entity.CreatedUserId = userId;
                        entry.Entity.LastUpdatedUserId = default;
                        entry.Entity.CreatedTime = dtNow;
                        entry.Entity.LastUpdatedTime = dtMin;
                        entry.Entity.DeleteTime = dtMin;
                        break;

                    case EntityState.Modified:
                        entry.Entity.LastUpdatedUserId = userId;
                        entry.Entity.LastUpdatedTime = dtNow;
                        break;
                }
            }
        }
    }
}
